from .celery_app import app
from vsogame.models.gateway import Gateway
from vsogame.models.account_his import AccountHistory
from vsogame.models.currency import Currency
from vsogame.models.deliver_info import DeliverInfo
from vsogame.models.account import Account
import datetime
import logging
import json

logger = logging.getLogger(__name__)


def calc_settle_amount(detail):
    total_amount = detail.real_amount

    for detail_ext in detail.detail_exts:
        total_amount -= detail_ext

    return total_amount


def calc_platform_fee(settle_amount):
    # TODO 需要考虑币种转换的问题
    from decimal import Decimal
    return settle_amount * Decimal.from_float(0.04)


def calc_settle_time(member, detail):
    return datetime.datetime.now()


@app.task
def order_fundin_finished(order):
    if order.is_paid():

        # 买家账务记录
        member = order.member
        with AccountHistory.atomic() as txn:
            try:
                # 1. 增加买家账务记录

                account_history = AccountHistory.get_or_none(
                    (AccountHistory.account == member.account) &
                    (AccountHistory.order == order)
                )

                if account_history:
                    logger.warn('订单{} 已经处理过,退出.', order.id)
                    return

                AccountHistory.create(
                    order=order,
                    direction=AccountHistory.CREDIT_DIRECTION,
                    amount=order.real_amount,
                    type='payment',
                    account=member.account,
                    remark='payment',
                    created_at=datetime.datetime.now(),
                    updated_at=datetime.datetime.now()
                )
                main_currency = Currency.get_main_currency()
                gateway = Gateway.get(Gateway.id == order.payment_method)
                # 2. 处理卖家账务记录
                for detail in list(order.details):

                    settle_amount = calc_settle_amount(detail)
                    logger.debug('订单明细 {}, 原金额 {}, 结算金额 {}', detail.id, detail.real_amount, settle_amount)
                    # 2.1 计算卖家待结算金额

                    dealer = detail.offer.member
                    dealer_account = dealer.account

                    if not dealer_account.currency.id == order.currency.id:
                        # 2.1.1如果订单币种与卖家账户币种不一至,需要转换
                        settle_amount = (settle_amount / main_currency.rate) * dealer_account.currency.rate
                        logger.debug('订单币种 {} 卖家账户币种 {} 转换过的结算金额 {}',
                                     order.currency.id,
                                     dealer_account.currency.id,
                                     settle_amount)
                    logger.debug('最终结算金额 {}', settle_amount)
                    platform_fee = calc_platform_fee(settle_amount)

                    # 2.2 计算平台佣金

                    logger.debug('订单详细金额{} 平台佣金 {}', detail.real_amount, platform_fee)
                    dealer_account.balance -= platform_fee

                    gateway.account.balance += platform_fee

                    gateway.account.save()

                    # 2.3.3 网关账户流水
                    AccountHistory.create(
                        account=gateway.account,
                        order=order,
                        direction=AccountHistory.DEBIT_DIRECTION,
                        amount=settle_amount,
                        type='fee',
                        created_at=datetime.datetime.now(),
                        updated_at=datetime.datetime.now(),
                        remark=detail.id
                    )

                    settle_time = calc_settle_time(dealer, detail)

                    if settle_time <= datetime.datetime.now():
                        # 直接结算
                        dealer_account.balance += settle_amount

                        AccountHistory.create(
                            account=dealer_account,
                            order=order,
                            direction=AccountHistory.DEBIT_DIRECTION,
                            amount=platform_fee,
                            type='income',
                            created_at=datetime.datetime.now(),
                            updated_at=datetime.datetime.now(),
                            settle_time=settle_time,
                            remark=detail.id
                        )
                    else:
                        # 加入待结算金额
                        dealer_account.pending_amount += settle_amount
                        AccountHistory.create(
                            account=dealer_account,
                            order=order,
                            direction=AccountHistory.DEBIT_DIRECTION,
                            amount=settle_amount,
                            type='income',
                            created_at=datetime.datetime.now(),
                            updated_at=datetime.datetime.now(),
                            settle_time=settle_time,
                            status='pending',
                            remark=detail.id
                        )
                    detail.settlement = True
                    detail.save()
                    dealer_account.save()
            except Exception as err:
                logger.error("处理订单完成事件失败:{}", err)
                txn.rollback()


@app.task
def delivery(order):
    pass
    if order.is_paid():
        order_detail_list = order.details
        for detail in order_detail_list:
            if detail.delivery_method == 'ticket':
                offer = detail.offer
                from ..models.inventory import Ticket
                count = detail.count
                ticket_list = list(Ticket.select().where(
                    (Ticket.offer == offer) & (Ticket.status == 'normal')).limit(count))

                if len(ticket_list) < count:
                    print('数目不够')

                else:
                    ticket_ids = [ticket.id for ticket in ticket_list]

                    update_num = Ticket.update(status='shipped').where(
                        (Ticket.id << ticket_ids)
                        & (Ticket.status == 'normal')).execute()
                    if not update_num == count:
                        print('数目不够2')

                delivery_info = DeliverInfo.create(
                    type='ticket',
                    trace_no='',
                    extension='',
                    deliver_time=datetime.datetime.now(),
                    status='done',
                    trace_info=json.dumps({
                        'ticket': [ticket.value for ticket in ticket_list]
                    })
                )

                detail.deliver_info = delivery_info

                offer.sales_count += count

                detail.save()
                offer.save()
                # for ticket in ticket_list:
                #     ticket.status = 'shipped'
                #     ticket.update()


def delivery_finished():
    pass
    # 给卖家增加待结算金额
